﻿using Microsoft.Win32;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using MessageBox = System.Windows.MessageBox;
using SaveFileDialog = Microsoft.Win32.SaveFileDialog;

namespace ZTZP_BEMSS_WPF
{
    // BidQuote 类也需要实现 INotifyPropertyChanged
    public class BidQuote : INotifyPropertyChanged
    {
        private string _bidCompany;
        public string BidCompany//公司名称
        {
            get { return _bidCompany; }
            set
            {
                _bidCompany = value;
                OnPropertyChanged(nameof(BidCompany));
            }
        }

        private double _bidPrice;//投标报价
        public double BidPrice
        {
            get { return _bidPrice; }
            set
            {
                _bidPrice = value;
                OnPropertyChanged(nameof(BidPrice));
            }
        }

        private double _discountRate;
        public double DiscountRate
        {
            get { return _discountRate; }
            set
            {
                _discountRate = value;
                OnPropertyChanged(nameof(DiscountRate));
            }
        }

        // INotifyPropertyChanged 实现
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public partial class ExcelReader
    {
        public static string OpenExcelFilePath()//导入Excel文件
        {
            // 创建一个OpenFileDialog实例
            Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();

            // 设置文件对话框的属性
            openFileDialog.Title = "选择要导入的Excel文件";
            openFileDialog.Filter = "Excel文件|*.xlsx;*.xls|所有文件|*.*";
            openFileDialog.FileName = ""; // 默认文件名为空
            openFileDialog.FilterIndex = 1; // 默认选择Excel文件类型

            // 显示文件对话框，并判断用户是否选择了文件
            bool? result = openFileDialog.ShowDialog();

            // 如果用户选择了文件（点击"打开"）
            if (result == true)
            {
                // 获取选择的文件路径
                string selectedFilePath = openFileDialog.FileName;

                // 显示选择的文件路径（可选）
                //MessageBox.Show($"即将导入文件：{selectedFilePath}");

                return selectedFilePath;
            }
            else
            {
                // 用户取消选择文件
                MessageBox.Show("未选择Excel文件");
                return null;
            }
        }

        //招标控制价BidControlPrice，
        public static ObservableCollection<BidQuote> ReadExcelFile(string filePath,double BidControlPrice= 1)
        {
            var bidQuotes = new ObservableCollection<BidQuote>();

            // 确保EPPlus的LicenseContext被设置为NonCommercial
            ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
            // 检查 filePath 是否为空
            if (string.IsNullOrEmpty(filePath))
            {
             
                return null ; // 返回 false 或者可以抛出异常，取决于需求
            }
            // 打开Excel文件
            using (var package = new ExcelPackage(new FileInfo(filePath)))
            {
                // 获取第一个工作表
                var worksheet = package.Workbook.Worksheets[0];

                // 获取表格的行数
                var rowCount = worksheet.Dimension.Rows;

                // 从第二行开始读取数据
                for (int row = 2; row <= rowCount; row++)
                {
                    var bidCompany = worksheet.Cells[row, 1].Text; // 第一列是投标单位
                    var bidPriceText = worksheet.Cells[row, 2].Text; // 第二列是投标报价
                    double discountRate = 1;//投标报价占招标控制价的比例
                    double bidPrice;

                    // 如果遇到空行（两列都为空），则停止读取
                    if (string.IsNullOrEmpty(bidCompany) && string.IsNullOrEmpty(bidPriceText))
                    {
                        break; // 遇到第一个空行就停止读取
                    }
                    // 尝试将投标报价转为数字
                    if (!double.TryParse(bidPriceText, out bidPrice))
                    {
                        bidPrice = 0; // 如果解析失败，则默认设置为0
                    }
                    else
                    {
                        // 使用 ToString 格式化为2位小数
                        bidPrice = double.Parse(bidPrice.ToString("F2"));
                    }
                    discountRate = (bidPrice- BidControlPrice) / BidControlPrice;//相对于投标报价的下浮率 25.34%
                    var bidQuote = new BidQuote
                    {
                        BidCompany = bidCompany,
                        BidPrice = bidPrice,
                        DiscountRate= discountRate
                    };

                    bidQuotes.Add(bidQuote);
                }
            }

            return bidQuotes;
        }
        public static void  DisplayBidQuotes(ObservableCollection<BidQuote> bidQuotes)
        {
            // 检查集合是否为空
            if (bidQuotes == null || bidQuotes.Count == 0)
            {
                MessageBox.Show("没有投标报价数据");
                return;
            }

            // 创建一个字符串构建器来存储输出信息
            StringBuilder outputBuilder = new StringBuilder();
            outputBuilder.AppendLine("投标报价明细：");
            outputBuilder.AppendLine("------------------------");

            // 遍历并格式化每个投标报价
            for (int i = 0; i < bidQuotes.Count; i++)
            {
                outputBuilder.AppendLine($"第 {i + 1} 家投标单位：");
                outputBuilder.AppendLine($"投标单位：{bidQuotes[i].BidCompany}");
                outputBuilder.AppendLine($"投标报价：{bidQuotes[i].BidPrice:F2} 万元");
                outputBuilder.AppendLine("------------------------");
            }

            // 显示总结信息
            outputBuilder.AppendLine($"共 {bidQuotes.Count} 家投标单位");


            Form_Messagebox messagebox = new Form_Messagebox();
            messagebox.ShowMessageInfo("各单位投标报价信息", outputBuilder.ToString());
            // 最终输出统计结果
        }
        //导出Excel表格
        public static string ExportExcelFile(ObservableCollection<BidQuote> bidquotes)
        {
            // 创建一个SaveFileDialog实例
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            // 设置文件对话框的属性
            saveFileDialog.Title = "选择要导出的Excel文件位置";
            saveFileDialog.Filter = "Excel文件|*.xlsx;*.xls|所有文件|*.*";
            saveFileDialog.FileName = "报价单"; // 建议的文件名
            saveFileDialog.FilterIndex = 1; // 默认选择Excel文件类型
            saveFileDialog.RestoreDirectory = true; // 保存后恢复上次浏览的目录

            // 显示文件对话框，并判断用户是否选择了文件
            bool? result = saveFileDialog.ShowDialog();

            // 如果用户选择了文件（点击"保存"）
            if (result == true)
            {
                // 获取选择的文件路径
                string selectedFilePath = saveFileDialog.FileName;

                // 导出Excel文件
                bool exportSuccess = ExportExcelFileToPath(selectedFilePath, bidquotes);

                if (exportSuccess)
                {
                    // 显示成功消息（可选）
                    MessageBox.Show($"文件已成功导出到：{selectedFilePath}");
                    return selectedFilePath;
                }
                else
                {
                    // 显示失败消息（可选）
                    MessageBox.Show("文件导出失败");
                    return null;
                }
            }
            else
            {
                // 用户取消选择文件
                MessageBox.Show("未选择导出Excel文件");
                return null;
            }
        }

        // 导出Excel文件到指定路径的辅助函数
        private static bool ExportExcelFileToPath(string filePath, ObservableCollection<BidQuote> bidquotes)
        {
            // 确保EPPlus的LicenseContext被设置为NonCommercial
            ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;

            // 创建一个新的Excel工作簿
            using (var package = new ExcelPackage())
            {
                // 添加一个工作表
                var worksheet = package.Workbook.Worksheets.Add("报价单");

                // 设置表头
                worksheet.Cells[1, 1].Value = "投标单位";
                worksheet.Cells[1, 2].Value = "投标报价(万元)";
                // 第一行背景色为绿色
                worksheet.Cells[1, 1, 1, 2].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                worksheet.Cells[1, 1, 1, 2].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Green);
                // 第一行添加过滤功能
                worksheet.Cells[1, 1, 1, 2].AutoFilter = true;//自动添加过滤的功能
                // 从第二行开始写入数据
                int row = 2;
                foreach (var bidQuote in bidquotes)
                {
                    worksheet.Cells[row, 1].Value = bidQuote.BidCompany;
                    worksheet.Cells[row, 2].Value = bidQuote.BidPrice;
                    row++;
                }
                // Auto fit columns to adjust width
                worksheet.Cells.AutoFitColumns();//自适应列宽
                // 保存到文件
                try
                {
                    FileInfo fileInfo = new FileInfo(filePath);
                    package.SaveAs(fileInfo);
                    return true;
                }
                catch (Exception ex)
                {
                    // 处理异常（可选）
                    System.Windows.MessageBox.Show($"导出失败：{ex.Message}");
                    return false;
                }
            }
        }
    }
    /// <summary>
    /// BidQuotePrice03.xaml 的交互逻辑
    /// </summary>
    public partial class BidQuotePrice03 : Window, INotifyPropertyChanged
    {
        private BidQuotePrice03()//构造函数
        {
            InitializeComponent();
            this.DataContext = this;//将 DataContext 设置为 this，表示窗口中的所有控件都可以直接绑定到BidQuotePrice03 类中的属性。
            InitBidQuotes();//初始化投标报价单位和投标报价
            InitFloatingK();//初始化下浮系数K
        }
        //根据投标报价和招标控制价计算 投标报价的下浮率
        public void InitBidQuotesFloatRate(List<int> FloatingRate_List, double BidControlPrice)
        {
            this.FloatingRate_List = FloatingRate_List;//下浮率Δ
            this.BidControlPrice = BidControlPrice;//招标控制价
            CalculateDiscountRates();

        }
        public void CalculateDiscountRates()//计算投标报价相对于招标控制价的下浮率
        {
            // 遍历所有 BidQuote
            foreach (var bidQuote in BidQuotes)
            {
                // 计算下浮率，并赋值给 DiscountRate
                if (this.BidControlPrice != 0) // 防止除以零的情况
                {
                    bidQuote.DiscountRate = (bidQuote.BidPrice - this.BidControlPrice) / this.BidControlPrice;
                }
                else
                {
                    bidQuote.DiscountRate = 0; // 如果 BidControlPrice 为 0，可以设置为默认值，或者根据需求调整
                }
            }
        }

        // 静态字段保存唯一实例
        private static BidQuotePrice03 _instance;
        public List<double> _FloatingK;//下浮系数K
        public string _StrFloatingK;//下浮系数转换为字符串

        public List<int> _FloatingRate;//下浮率%(6 7 8 9 10 11)取百分号里面的数值，取整数，从上一个对话框传过来
        public string _StrFloatingRate;//下浮率转换为字符串

        public double _BidControlPrice;//招标控制价,从上一个对话框传过来
        public event PropertyChangedEventHandler PropertyChanged;
        // 定义一个字段来控制使用中文顿号还是英文逗号
        private bool _useChineseComma = true; // 默认为中文顿号
        private ObservableCollection<BidQuote> _BidQuotes;//各个单位的投标报价
        public ObservableCollection<BidQuote> BidQuotes//各个单位的投标报价
        {
            get { return _BidQuotes; }
            set
            {
                _BidQuotes = value;
                OnPropertyChanged(nameof(BidQuotes)); // 通知属性发生变化
            }
        }
        public double BidControlPrice//招标控制价
        {
            get { return _BidControlPrice; }
            set
            {
                _BidControlPrice = value;
                OnPropertyChanged(nameof(BidControlPrice)); // 通知属性发生变化
            }
        }

        Dictionary<Tuple<double, double, double>, double> m_BasePrices;//Tuple<double, double>->键是（B值、下浮率和下浮系数）的组合,值double ->评标基准价
        private List<BasePriceEntry> _BasePriceEntries;
        public List<BasePriceEntry> m_BasePriceEntries//下浮率，下浮系数和评标基准价
        {
            get { return _BasePriceEntries; }
            set
            {
                _BasePriceEntries = value;
                OnPropertyChanged(nameof(m_BasePriceEntries)); // 通知属性发生变化
            }
        }

        //导入表格
        private void ImportExcelButton_Click(object sender, RoutedEventArgs e)
        {
            //MessageBox.Show("招标控制价为: " + _BidControlPrice.ToString());

            string filepath = ExcelReader.OpenExcelFilePath();
            BidQuotes = ExcelReader.ReadExcelFile(filepath, _BidControlPrice);
            // 显示一个 MessageBox
            ExcelReader.DisplayBidQuotes(BidQuotes);

            // 这里可以加入导入Excel的代码逻辑
        }
        //导出表格
        private void ExportExcelButton_Click(object sender, RoutedEventArgs e)
        {
            //ExcelReader.DisplayBidQuotes(BidQuotes);//弹出对话框显示要导出的数据
            string path= ExcelReader.ExportExcelFile(BidQuotes);//导出数据到Excel文档
                                                                // 提示用户是否打开Excel文件
            MessageBoxResult openFileResult = MessageBox.Show("是否打开导出的Excel文件？", "提示", MessageBoxButton.YesNo);

            if (openFileResult == MessageBoxResult.Yes&& (path!=null))
            {
                // 用户选择打开文件
                Process.Start(path);
            }
        }
        
        private void InitBidQuotes()
        {
            BidQuotes = new ObservableCollection<BidQuote>
            {
                new BidQuote { BidCompany = "中铁装配科技公司", BidPrice = 1000},
                new BidQuote { BidCompany = "中铁装配实业", BidPrice = 1200},
                new BidQuote { BidCompany = "新疆指挥部", BidPrice = 1500}
             };      
        }

        private void InitFloatingK()
        {
            FloatingK_List = new List<double>
            {
                95,
                95.5,
                96,
                96.5,
                97,
                97.5,
                98
            };
        }
        // Notify property change
        protected void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
        #region 下浮率的数据绑定
        // Property for the floating rates list
        //下浮率属性 上一个对话框传过来的数据，都是整数 还没有除100
        public List<int> FloatingRate_List
        {
            get { return _FloatingRate; }
            set
            {
                _FloatingRate = value;
                // 根据 _useChineseComma 决定分隔符
                string separator = _useChineseComma ? "、" : ",";
                StrFloatingRate = string.Join(separator, _FloatingRate); // Convert list to string with Chinese comma
                OnPropertyChanged(nameof(FloatingRate_List));
            }
        }
        public string StrFloatingRate//下浮率属性
        {
            get { return _StrFloatingRate; }
            set
            {
                _StrFloatingRate = value;
                OnPropertyChanged(nameof(StrFloatingRate));
            }
        }


        public List<double> FloatingK_List//下浮系数数字属性
        {
            get { return _FloatingK; }
            set
            {
                _FloatingK = value;
                // 根据 _useChineseComma 决定分隔符
                string separator = _useChineseComma ? "、" : ",";
                StrFloatingK = string.Join(separator, _FloatingK); // Convert list to string with Chinese comma
                OnPropertyChanged(nameof(FloatingK_List));
            }
        }


        public string StrFloatingK//下浮系数字符串属性
        {
            get { return _StrFloatingK; }
            set
            {
                _StrFloatingK = value;
                OnPropertyChanged(nameof(StrFloatingK));
            }
        }







        #endregion 下浮率的数据绑定
        void ShowInfo()//显示所有的信息
        {

            //public ObservableCollection<BidQuote> _BidQuotes;//投标价格
            //public double _BidControlPrice;}//招标控制价
            //public List<int> _FloatingK;//下浮系数K
            //public List<int> _FloatingRate;//下浮率Δ
            StringBuilder message = new StringBuilder();
            message.AppendLine("招标控制价: " + _BidControlPrice);
            foreach (var floatingK in _FloatingK)
            {
                message.AppendLine("下浮系数K: " + floatingK);
            }
            foreach (var floatingRate in _FloatingRate)
            {
                message.AppendLine("下浮率 Δ: " + floatingRate);
            }
            foreach (var bidQuote in _BidQuotes)
            {
                message.AppendLine("公司名称: " + bidQuote.BidCompany);
                message.AppendLine("投标报价: " + bidQuote.BidPrice);
                message.AppendLine("--------------------------"); // Add a new line for better readability between different bid quotes
            }
            // 显示信息
            System.Windows.MessageBox.Show(message.ToString(), "Bid Information", (MessageBoxButton)MessageBoxButtons.OK, (MessageBoxImage)MessageBoxIcon.Information);
        }

        // 提供对单例实例的访问
        public static BidQuotePrice03 Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new BidQuotePrice03();
                }
                return _instance;
            }

        }
        //下一步
        public Dictionary<Tuple<double, double, double>, double> CalculateAndShowInfoBasePrice()//计算不同组合下的评标基准价和显示相应的评标基准价
        {
            // 创建一个字典来存储 B值、下浮率和下浮系数的组合及对应的评标基准价
            Dictionary<Tuple<double, double, double>, double> basePrices = new Dictionary<Tuple<double, double, double>, double>();

            // 用于统计 B 值、下浮率和下浮系数的出现次数
            var bValueCounts = new Dictionary<double, int>();
            var floatingRateCounts = new Dictionary<double, int>();
            var floatingKCounts = new Dictionary<double, int>();

            #region 1、遍历不同的下浮率和下浮系数和B值，计算评标基准价
            foreach (var floatingRate in FloatingRate_List) // 下浮率
            {
                foreach (var floatingK in FloatingK_List) // 下浮系数
                {
                    // Step 5: 计算 A 值
                    double A = BidControlPrice * (1 - (floatingRate / 100.0));

                    // Step 6: 计算 C 值
                    double topPrice = BidQuotes.Average(b => b.BidPrice) * 0.7 + BidControlPrice * 0.3;
                    // 确保 BidQuotes 不为空，并且存在满足条件的数据
                    var validCValues = BidQuotes.Where(b => b.BidPrice >= topPrice * 0.75 && b.BidPrice <= topPrice).ToList();

                    // 只有在 validCValues 非空时，才调用 Min()
                    double minC = 0;
                    if (validCValues.Any())
                    {
                        minC = validCValues.Min(b => b.BidPrice);
                    }
                    else
                    {
                        // 如果没有符合条件的投标价格，设置 minC 为一个合适的默认值或进行处理
                        // 例如，设置为 0 或其他值，取决于实际情况
                        minC = 0; // 或者您可以选择其他默认值
                    }

                    // Step 7: 计算 B 值
                    var BQG1 = BidQuotes.Where(b => b.BidPrice >= 0.95 * A).ToList();
                    var BQG2 = BidQuotes.Where(b => b.BidPrice < 0.95 * A && b.BidPrice >= 0.92 * A).ToList();
                    var BQG3 = BidQuotes.Where(b => b.BidPrice < 0.92 * A && b.BidPrice >= 0.89 * A).ToList();
                    var BQG4 = BidQuotes.Where(b => b.BidPrice < 0.89 * A).ToList();

                    List<BidQuote> BRange = new List<BidQuote>();

                    // 从 BQG2 中随机抽取一个元素
                    if (BQG2.Any())
                        BRange.Add(BQG2[new Random().Next(BQG2.Count)]);

                    // 从 BQG3 中随机抽取一个元素
                    if (BQG3.Any())
                        BRange.Add(BQG3[new Random().Next(BQG3.Count)]);

                    // 将 BQG4 的所有元素加入 BRange
                    BRange.AddRange(BQG4);

                    // 移除包含 C 值的元素
                    BRange.RemoveAll(b => b.BidPrice == minC);

                    // 如果 BRange 非空，按顺序循环选择 B 值
                    foreach (var bid in BRange)//循环B的值
                    {
                        // 获取当前的 B 值
                        double B = bid.BidPrice;

                        // Step 8: 计算投标基准价
                        double basePrice = (A * 0.5 + B * 0.3 + minC * 0.2) * (floatingK / 100);
                        basePrice = Math.Round(basePrice, 2); // 保留两位小数

                        // 将 B 值、下浮率、下浮系数作为 key 存入字典，评标基准价作为 value
                        var key = new Tuple<double, double, double>(B, floatingRate, floatingK);
                        basePrices[key] = basePrice;

                        // 统计 B 值、下浮率、下浮系数的出现次数
                        if (!bValueCounts.ContainsKey(B)) bValueCounts[B] = 0;
                        bValueCounts[B]++;

                        if (!floatingRateCounts.ContainsKey(floatingRate)) floatingRateCounts[floatingRate] = 0;
                        floatingRateCounts[floatingRate]++;

                        if (!floatingKCounts.ContainsKey(floatingK)) floatingKCounts[floatingK] = 0;
                        floatingKCounts[floatingK]++;
                    }
                }
            }
            #endregion 遍历不同的下浮率和下浮系数和B值，计算评标基准价

            #region 2、输出 B 值、下浮率和下浮系数的个数，以及它们对应的值，以及输出投标单位的名称和投标报价

            string message = "B 值统计：\n";
            foreach (var bCount in bValueCounts)
            {
                message += $"B 值: {bCount.Key}, 次数: {bCount.Value}\n";
            }

            message += "\n下浮率统计：\n";
            foreach (var rateCount in floatingRateCounts)
            {
                message += $"下浮率: {rateCount.Key}%, 次数: {rateCount.Value}\n";
            }

            message += "\n下浮系数统计：\n";
            foreach (var kCount in floatingKCounts)
            {
                message += $"下浮系数: {kCount.Key}, 次数: {kCount.Value}\n";
            }

            // 输出 basePrices 的个数和对应的值
            message += $"\nbasePrices 的个数: {basePrices.Count}\n";
            foreach (var kv in basePrices)
            {
                message += $"B 值: {kv.Key.Item1}, 下浮率: {kv.Key.Item2}%, 下浮系数: {kv.Key.Item3}, 评标基准价: {kv.Value}\n";
            }

            // 输出单位的总个数和每个单位的投标报价
            message += $"\n单位总个数: {BidQuotes.Count}\n";
            message += "每个单位的投标报价：\n";
            foreach (var bidQuote in BidQuotes)
            {
                message += $"单位名称: {bidQuote.BidCompany}, 投标报价: {bidQuote.BidPrice}\n";
            }
            //private ObservableCollection<BidQuote> _BidQuotes;//各个单位的投标报价
            #region 显示计算参数和计算结果
            Form_Messagebox messagebox = new Form_Messagebox();
            messagebox.Title="评标基准价信息";
            messagebox.SetMessage(message);
            // 最终输出统计结果
            messagebox.ShowDialog();//模态对话框
            #endregion 显示计算参数和计算结果
            // 返回存储所有基准价的字典
            #endregion 2、输出 B 值、下浮率和下浮系数的个数，以及它们对应的值，以及输出投标单位的名称和投标报价
            
            return basePrices;
        }

        //将Tuple转为结构体集合
        public List<BasePriceEntry> ConvertToBasePriceEntries(Dictionary<Tuple<double, double, double>, double> BasePrices)
        {
            return BasePrices
        .Select(kv => new BasePriceEntry(
             kv.Key.Item1,  // B值 (BValue)
            kv.Key.Item2,  // 下浮率 (FloatingRate)
            kv.Key.Item3,  // 下浮系数 (FloatingK)          
            kv.Value       // 评标基准价 (BasePrice)
        ))
        .ToList();
        }

            //输出不同下浮率 下浮系数下的评标基准价
            public void DisplayBasePrices(Dictionary<Tuple<double, double, double >, double> basePrices, List<BasePriceEntry> BasePriceEntries=null)
        {
            // 创建一个 StringBuilder 来构建输出的字符串
            StringBuilder sb = new StringBuilder();

            // 遍历字典中的每个键值对
            sb.AppendLine("转换前的评标基准价：");
            foreach (var item in basePrices)
            {
                // 获取字典的键 (下浮率, 下浮系数)
                var key = item.Key;
                double BValue= key.Item1;//B值
                double floatingRate = key.Item2;//下浮率Δ
                double floatingK = key.Item3;//下浮系数

                // 获取字典的值（评标基准价）
                double basePrice = item.Value;

                // 将信息格式化并添加到 StringBuilder
                sb.AppendLine($"转化前：B值：{BValue},下浮率: {floatingRate}, 转化前：下浮系数: {floatingK}, 转化前：评标基准价: {basePrice}");
            }
            // 如果 BasePriceEntries 不为空，输出列表中的数据
            if (BasePriceEntries != null && BasePriceEntries.Count > 0)
            {
                sb.AppendLine();  // 增加一个空行，方便区分不同部分
                sb.AppendLine("BasePriceEntries 转换后的评标基准价：");

                foreach (var entry in BasePriceEntries)
                {
                    sb.AppendLine($"转化后：B值：{entry.BValue},下浮率: {entry.FloatingRate}, 转化后：下浮系数: {entry.FloatingK}, 转化后：评标基准价: {entry.BasePrice}");
                }
            }

            // 显示输出的内容到 MessageBox
            MessageBoxResult messageBoxResult = MessageBox.Show(sb.ToString(), "转换前后的评标基准价");
        }

        private void Button_ClickNext(object sender, RoutedEventArgs e)//下一步
        {
            #region 1、计算不同下浮系数 下浮率 不同投标报价下的评标基准价

            //显示招标控制价、下浮系数、下浮率、投标单位名称，投标报价等信息
            //ShowInfo();//显示计算参数

            #endregion

            #region 2、计算不同下浮系数 下浮率 不同投标报价下的评标基准价
            //2-计算不同下浮系数下浮率下的评标基准价
            //2.0、从public List<int> FloatingRate_List抽取下浮率Δ和 从public List<double> FloatingK_List抽取下浮系数K
            //2.01、`招标控制价格为 BidControlPrice
            //2.1、计算A值：计算A值 A=招标控制价X（100%-下浮率Δ）
            //2.2、计算C值:TOTAL=评标价算术平均值X70%+招标控制价X30%,然后范围是（TOTAL*75%，TOTAL），求出投标价在（TOTAL*75%，TOTAL）中的最小值
            //2.3、计算B值：对BidQuotes进行分组，分为四个组G1 G2 G3 G4  第一组 G1>=95%A,第二组 95%>G2>=92%,第三组 92%>G3>=89%,第四组 G4<89%
            //2.4、循环投标报价 public ObservableCollection<BidQuote> BidQuotes每个元素BidQuote  ，如果BidQuote的BidPrice在G1组，放入BG1组，如果BidQuote的BidPrice在G2组，放入BG2组;如果BidQuote的BidPrice在G3组，放入BG3组；如果BidQuote的BidPrice在G4组，放入BG4组
            //2.5、形成B值的抽取范围BG：BG1组直接舍弃，从BG2组中随机抽取一个放入BG,从BG3组中随机抽取一个放入BG，BG4所有的元素都放入BG，这样BG集合就形成了，如果C值在BG之内，将C值剔除，这样最终的BG就形成了。然后从BG中随机抽取一个元素，获得了B值
            //2.6、计算投标基准价：BasePrice=（A*50%+B*30%+C*20%）*K
            m_BasePrices = CalculateAndShowInfoBasePrice();//计算不同下浮率、下浮率下的评标基准价           
            m_BasePriceEntries=ConvertToBasePriceEntries(m_BasePrices);//将不同下浮率、下浮率下的评标基准价  转换为一个集合
            //DisplayBasePrices(m_BasePrices, m_BasePriceEntries); //输出Dictionary<Tuple<double, double>, double> m_BasePrices;//Tuple<double, double>->键是下浮率和下浮系数的组合,值double ->评标基准价 显示计算后的结果
           

            #endregion
            // 获取 BasePriceCalRes04 的单例实例
            BasePriceCalRes04 BQC04 = BasePriceCalRes04.Instance;
            BQC04.GetBasePriceEntries(m_BasePriceEntries);//转换为对话框4的可以修改界面的参数
            BQC04.GetBidQuotes(_BidQuotes);//将投标单位设置给下一个对话框
            // 如果窗口没有显示，则显示它
            if (!BQC04.IsVisible)
            {
                // 计算窗口的位置，使得 StartUpImageDialog01 的中心在当前窗口的中心
                BQC04.Left = this.Left + (this.Width - BQC04.Width) / 2;
                BQC04.Top = this.Top + (this.Height - BQC04.Height) / 2;
                BQC04.Show();
            }

            // 隐藏当前窗口，而不是关闭它
            this.Hide();

        }
        //上一步
        private void Button_ClickPrevious(object sender, RoutedEventArgs e)
        {

            CalculationParameters02 CP = CalculationParameters02.Instance;
            // 如果窗口没有显示，则显示
            if (!CP.IsVisible)
            {
                // 计算窗口的位置，使得 StartUpImageDialog01 的中心在当前窗口的中心
                CP.Left = this.Left + (this.Width - CP.Width) / 2;
                CP.Top = this.Top + (this.Height - CP.Height) / 2;
                CP.Show();
            }
            this.Hide();
        }
    }
}
